/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    i2c.c
  * @brief   This file provides code for the configuration
  *          of the I2C instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"

/* USER CODE BEGIN 0 */
#include "usart.h"
#include <stdio.h>

#define EEPROM_ADDRESS  0xA0
#define EEPROM_PAGESIZE 8
#define DATA_Size 256
#define EEP_FirstPage 0x00
/* USER CODE END 0 */

I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2;

/* I2C1 init function */
void MX_I2C1_Init(void)
{

  /* USER CODE BEGIN I2C1_Init 0 */

  /* USER CODE END I2C1_Init 0 */

  /* USER CODE BEGIN I2C1_Init 1 */

  /* USER CODE END I2C1_Init 1 */
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 400000;
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_16_9;
  hi2c1.Init.OwnAddress1 = 0;
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.OwnAddress2 = 0;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C1_Init 2 */
  __HAL_I2C_ENABLE (&hi2c1);
  /* USER CODE END I2C1_Init 2 */

}
/* I2C2 init function */
void MX_I2C2_Init(void)
{

  /* USER CODE BEGIN I2C2_Init 0 */

  /* USER CODE END I2C2_Init 0 */

  /* USER CODE BEGIN I2C2_Init 1 */

  /* USER CODE END I2C2_Init 1 */
  hi2c2.Instance = I2C2;
  hi2c2.Init.ClockSpeed = 100000;
  hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;
  hi2c2.Init.OwnAddress1 = 0;
  hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c2.Init.OwnAddress2 = 0;
  hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  if (HAL_I2C_Init(&hi2c2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2C2_Init 2 */
  __HAL_I2C_ENABLE (&hi2c2 );
  /* USER CODE END I2C2_Init 2 */

}

void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspInit 0 */

  /* USER CODE END I2C1_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C1 GPIO Configuration
    PB8     ------> I2C1_SCL
    PB9     ------> I2C1_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    __HAL_AFIO_REMAP_I2C1_ENABLE();

    /* I2C1 clock enable */
    __HAL_RCC_I2C1_CLK_ENABLE();
  /* USER CODE BEGIN I2C1_MspInit 1 */

  /* USER CODE END I2C1_MspInit 1 */
  }
  else if(i2cHandle->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspInit 0 */

  /* USER CODE END I2C2_MspInit 0 */

    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**I2C2 GPIO Configuration
    PB10     ------> I2C2_SCL
    PB11     ------> I2C2_SDA
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* I2C2 clock enable */
    __HAL_RCC_I2C2_CLK_ENABLE();
  /* USER CODE BEGIN I2C2_MspInit 1 */

  /* USER CODE END I2C2_MspInit 1 */
  }
}

void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{

  if(i2cHandle->Instance==I2C1)
  {
  /* USER CODE BEGIN I2C1_MspDeInit 0 */

  /* USER CODE END I2C1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_I2C1_CLK_DISABLE();

    /**I2C1 GPIO Configuration
    PB8     ------> I2C1_SCL
    PB9     ------> I2C1_SDA
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_8);

    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_9);

  /* USER CODE BEGIN I2C1_MspDeInit 1 */

  /* USER CODE END I2C1_MspDeInit 1 */
  }
  else if(i2cHandle->Instance==I2C2)
  {
  /* USER CODE BEGIN I2C2_MspDeInit 0 */

  /* USER CODE END I2C2_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_I2C2_CLK_DISABLE();

    /**I2C2 GPIO Configuration
    PB10     ------> I2C2_SCL
    PB11     ------> I2C2_SDA
    */
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10);

    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11);

  /* USER CODE BEGIN I2C2_MspDeInit 1 */

  /* USER CODE END I2C2_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */
uint32_t I2C_EE_PageWrite(uint8_t* pBuffer, uint8_t WriteAddr, uint8_t NumByteToWrite)
{
	HAL_StatusTypeDef status = HAL_OK;
	status = HAL_I2C_Mem_Write (&hi2c1,EEPROM_ADDRESS,WriteAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,NumByteToWrite,100);
	
	 while(HAL_I2C_GetState(&hi2c1) !=HAL_I2C_STATE_READY )
 {
 }
 while(HAL_I2C_IsDeviceReady(&hi2c1,EEPROM_ADDRESS,300,300) ==HAL_TIMEOUT )
 {
 }
  while(HAL_I2C_GetState(&hi2c1) !=HAL_I2C_STATE_READY )
 {
 }
   return status;
}

void I2C_EE_BufferWrite(uint8_t*pBuffer,uint8_t WriteAddr, uint16_t NumByteToWrite)
{
	uint8_t NumOfPage =0, NumOfSingle =0, Addr=0,count=0;
	Addr = WriteAddr %EEPROM_PAGESIZE;
	count =EEPROM_PAGESIZE -Addr;
	NumOfPage =NumByteToWrite/EEPROM_PAGESIZE;
	NumOfSingle =NumByteToWrite%EEPROM_PAGESIZE;
	
	if(Addr ==0){
	  if(NumOfPage==0){
			I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
		}
		else{
		while(NumOfPage--){
		 I2C_EE_PageWrite(pBuffer,WriteAddr,EEPROM_PAGESIZE);
			WriteAddr += EEPROM_PAGESIZE;
			pBuffer += EEPROM_PAGESIZE;
		}
		if(NumOfPage!=0){
			I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
		}
		}
		}
	else{
		if(NumOfPage ==0){
			I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
		}
	else{
		NumByteToWrite-= count;
		NumOfPage = NumByteToWrite/EEPROM_PAGESIZE;
	  NumOfSingle = NumByteToWrite % EEPROM_PAGESIZE;
		
		if(count!=0){
			I2C_EE_PageWrite(pBuffer,WriteAddr,count);
      WriteAddr += count;
		  pBuffer += count;
		}
		while(NumOfSingle--){
		 I2C_EE_PageWrite(pBuffer,WriteAddr,EEPROM_PAGESIZE);
			WriteAddr += EEPROM_PAGESIZE;
			pBuffer += EEPROM_PAGESIZE;			
		}
		if(NumOfSingle!=0){
			I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);
		}
	}
	}
}


uint32_t I2C_EE_BufferRead(uint8_t*pBuffer,uint8_t ReadAddr,uint16_t NumByteToRead)
{
	HAL_StatusTypeDef status = HAL_OK;
  status = HAL_I2C_Mem_Read(&hi2c1,EEPROM_ADDRESS,ReadAddr,I2C_MEMADD_SIZE_8BIT,pBuffer,NumByteToRead,100);
	return status;
}


uint8_t I2C_Buffer_Write[256];
uint8_t I2C_Buffer_Read[256];

uint8_t I2C_Test(void)
{
  uint16_t i;            //  uint8_t i; 8的话,i<DATA_Size,会报警告. 因为uint8_t的数值范围是0-255哈，共256个数，而不是到256哦.
	
	printf("净含量，你写入的数据: \r\n");
  for(i=0;i<DATA_Size ;i++){
	 I2C_Buffer_Write[i] = i;
  printf("0x%02X  ",I2C_Buffer_Write[i]);	
  if(i%16 == 15){               
	 printf(" \r\n");                                                                             
	}	
}	                                                                              
 I2C_EE_BufferWrite(I2C_Buffer_Write,EEP_FirstPage,DATA_Size);  

printf("净含量，你读出的数据: \r\n");
		I2C_EE_BufferRead(I2C_Buffer_Read,EEP_FirstPage,DATA_Size);
		for(i=0; i<DATA_Size;i++)
			{	
				
				if(I2C_Buffer_Read[i] !=I2C_Buffer_Write[i] )
			{	
				printf("0x%02X  ",I2C_Buffer_Read[i]);
				printf("错误:I2C EEPROM写入与读出的数据不一致 \r\n");
				return 0;
			}
			else{
		printf("0x%02X  ", I2C_Buffer_Read[i]);
		if(i%16 == 15)    
		printf("  \r\n");
	}

}
	printf("净含量，I2C(AT24C02)读写测试成功 \r\n");
	return 1;
		
}

/* USER CODE END 1 */
